package repository

import (
	"gorm.io/gorm"
	"shop-common/utils/pagehelper"
	"shop-common/utils/queryWrapper"
	"shop-sys/model"
	"shop-sys/pkg/vo"
	"strings"
)

type ISysUserRepository interface {
	CheckUserExist(*gorm.DB, *queryWrapper.WherePair) (bool, error)
	Create(*gorm.DB, *model.SysUser) error
	FindByIdUser(*gorm.DB, uint) (*model.SysUser, error)
	FindOne(*gorm.DB, *queryWrapper.WherePair) (*model.SysUser, error)
	FindByPerms(*gorm.DB, *queryWrapper.WherePair) ([]string, error)
	Updates(*gorm.DB, uint, map[string]interface{}) error
	Delete(*gorm.DB, uint) error
	FindPage(*gorm.DB, *pagehelper.Params) ([]*vo.SimpleSysUserVO, error)
	Count(*gorm.DB, *pagehelper.Params) (int64, error)
}

type sysUserRepository struct {
}

func NewSysUserRepository() ISysUserRepository {
	return &sysUserRepository{}
}

func (u *sysUserRepository) CheckUserExist(db *gorm.DB, pair *queryWrapper.WherePair) (exist bool, err error) {
	var count int64
	tx := db.Select("id").Model(&model.SysUser{})
	err = queryWrapper.ReuseWherePair(tx, pair).Count(&count).Error
	if err != nil {
		return false, err
	}

	return count > 0, nil
}

func (u *sysUserRepository) Create(db *gorm.DB, sysUser *model.SysUser) error {
	return db.Create(sysUser).Error
}

func (u *sysUserRepository) FindByIdUser(db *gorm.DB, userId uint) (user *model.SysUser, err error) {
	return user, db.Model(&model.SysUser{}).First(&user, userId).Error
}

func (u *sysUserRepository) FindOne(db *gorm.DB, pair *queryWrapper.WherePair) (user *model.SysUser, err error) {
	tx := db.Model(&model.SysUser{})
	tx = queryWrapper.ReuseWherePair(tx, pair)
	return user, tx.First(&user).Error
}

type partPermissionList struct {
	Perms string
}

//查询用户的所有权限，userId是1则查询全部
func (u *sysUserRepository) FindByPerms(db *gorm.DB, wp *queryWrapper.WherePair) (permsList []string, err error) {
	var perms []partPermissionList
	// 传递是空则查询全部
	if wp == nil {
		if err := db.Scopes(findPerms).Find(&perms).Error; err != nil {
			return nil, err
		}
	} else {
		if err := db.Scopes(findByIdPerms).Where(wp.Query, wp.Args...).Find(&perms).Error; err != nil {
			return nil, err
		}
	}

	for _, item := range perms {
		if item.Perms != "" {
			permsList = append(permsList, strings.Split(item.Perms, ",")...)
		}
	}
	return
}

func findPerms(db *gorm.DB) *gorm.DB {
	return db.Table("tz_sys_user_role ur").
		Select("m.perms").
		Joins("LEFT JOIN tz_sys_role_menu rm ON 1 = 1").
		Joins("LEFT JOIN tz_sys_menu m ON 1 = 1")
}

func findByIdPerms(db *gorm.DB) *gorm.DB {
	return db.Table("tz_sys_user_role ur").
		Select("m.perms").
		Joins("LEFT JOIN tz_sys_role_menu rm ON ur.role_id = rm.role_id").
		Joins("LEFT JOIN tz_sys_menu m ON rm.menu_id = m.menu_id")
}

func (u *sysUserRepository) Updates(db *gorm.DB, id uint, columns map[string]interface{}) error {
	return db.Model(&model.SysUser{}).Where("id = ?", id).Updates(columns).Error
}

func (u *sysUserRepository) Delete(db *gorm.DB, userId uint) error {
	return db.Delete(&model.SysUser{}, userId).Error
}

func (r *sysUserRepository) FindPage(db *gorm.DB, params *pagehelper.Params) (list []*vo.SimpleSysUserVO, err error) {
	tx := queryWrapper.ReuseWherePair(db.Model(&model.SysUser{}), params.WherePair)
	return list, tx.Scopes(pagehelper.Paginate(params.Current, params.Size)).Find(&list).Error
}

func (r *sysUserRepository) Count(db *gorm.DB, params *pagehelper.Params) (count int64, err error) {
	tx := queryWrapper.ReuseSelect(db.Model(&model.SysUser{}), params.SelectFields)
	return count, queryWrapper.ReuseWherePair(tx, params.WherePair).Count(&count).Error
}
